package io.gitee.kotle.android.mvvm

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.RectF
import android.os.Bundle
import android.util.AttributeSet
import android.view.*
import android.widget.FrameLayout
import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatDialogFragment
import io.gitee.kotle.android.R
import io.gitee.kotle.android.delegate.unsafeLazy
import io.gitee.kotle.android.mvvm.mvvminterface.IBaseMvvm
import io.gitee.kotle.android.mvvm.mvvminterface.ScreenOrientationHelper
import io.gitee.kotle.android.utils.fullScreen
import io.gitee.kotle.android.utils.transparentStatusBar

/**
 * 所有dialog的基类
 */
abstract class MvvmDialog : AppCompatDialogFragment(), IBaseMvvm {
    private val screenOrientationHelper by unsafeLazy { ScreenOrientationHelper(this) }
    private var dialogView: View? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //用于响应触摸外部消失
        val rootTouchView = TouchDismissView(inflater.context)
        val contentViewGroup =
            onHandleCreateMvvmViewType(layoutInflater, rootTouchView, savedInstanceState)
                ?: return null
        dialogView = contentViewGroup
        val oldLp = contentViewGroup.layoutParams
        val newLp = if (oldLp == null) {
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.WRAP_CONTENT
            )
        } else {
            if (oldLp is FrameLayout.LayoutParams) {
                oldLp
            } else {
                FrameLayout.LayoutParams(
                    oldLp.width,
                    oldLp.height
                )
            }
        }
        onRootViewLayoutParams(contentViewGroup, newLp)
        rootTouchView.addView(contentViewGroup, newLp)
        return rootTouchView
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.setBackgroundResource(R.drawable.mvvm_dialog_background)
        onUpdateWindowAttributes()
        onViewCreatedFinish(this, savedInstanceState, resources)
    }

    /**
     * 触摸外面是否可以取消
     */
    var isCanceledOnTouchOutside = true

    /**
     * 对话框的window
     */
    val window: Window?
        get() = dialog?.window

    /**
     * 设置窗口动画
     */
    fun setWindowAnimations(@StyleRes resId: Int) {
        window?.setWindowAnimations(resId)
    }

    /**
     * 更新窗口参数
     */
    protected open fun onUpdateWindowAttributes() {
        updateWindowAttributes()
    }

    /**
     * 是否是全屏
     */
    open var isFullScreen = false

    /**
     * 设置主题
     */
    override fun getTheme(): Int {
        return R.style.MvvmDialogStyle
    }

    /**
     * 设置布局参数
     */
    protected open fun onRootViewLayoutParams(view: View, layoutParams: FrameLayout.LayoutParams) {
        getMvvmWindowAnimations(view, layoutParams)?.let {
            setWindowAnimations(it)
        }
    }

    /**
     * 设置对话框进入退出动画
     */
    @StyleRes
    protected open fun getMvvmWindowAnimations(
        view: View,
        layoutParams: FrameLayout.LayoutParams
    ): Int? {
        return when (layoutParams.gravity) {
            Gravity.BOTTOM -> {
                R.style.PopupWindowBottomIn
            }
            Gravity.TOP -> {
                R.style.PopupWindowTopIn
            }
            else -> {
                R.style.AnimScaleCenter
            }
        }
    }

    private fun updateWindowAttributes() {
        if (isFullScreen) {
            window?.fullScreen(true)
        } else {
            window?.transparentStatusBar(
                isBlackStatusBarTextColor = false,
                isBlackNavigationBarTextColor = false,
            )
        }
    }

    private inner class TouchDismissView : FrameLayout {
        constructor(context: Context) : super(context)
        constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
            context,
            attrs,
            defStyleAttr
        )

        private val bounds = RectF()
        private var canDismissWhenDown = false

        /**
         * 不用点击事件处理是防止点击穿透
         */
        @SuppressLint("ClickableViewAccessibility")
        override fun onTouchEvent(ev: MotionEvent?): Boolean {
            when (ev?.action) {
                MotionEvent.ACTION_DOWN -> {
                    canDismissWhenDown = checkCanDismiss(ev)
                }
                MotionEvent.ACTION_UP -> {
                    if (canDismissWhenDown && checkCanDismiss(ev)) {
                        dismiss()
                    }
                }
                else -> {
                }
            }
            return true
        }

        private fun checkCanDismiss(ev: MotionEvent): Boolean {
            val view = dialogView
            if (view == null) {
                if (isCancelable && isCanceledOnTouchOutside) {
                    return true
                }
            } else {
                bounds.set(
                    view.left.toFloat(),
                    view.top.toFloat(),
                    view.right.toFloat(),
                    view.bottom.toFloat()
                )
                if (!bounds.contains(ev.x, ev.y)) {
                    if (isCancelable && isCanceledOnTouchOutside) {
                        return true
                    }
                }
            }
            return false
        }
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        checkScreenPortrait(resources)
    }

    final override fun checkScreenPortrait(resources: Resources) {
        screenOrientationHelper.checkScreenPortrait(resources)
    }
}